﻿namespace NTLib.Core.UTest.Timers
{
    using Core.Timers;
    using Exceptions;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Test.Resources;

    [TestClass]
    public class TimerUTest : BaseTestClass
    {
        #region Fields

        private const string TIMER_CATEGORY = "Timer";

        #endregion

        #region Methods

        [TestCategory(TIMER_CATEGORY)]
        [TestMethod]
        public void Timer_SimpleUsage()
        {
            TimeSpan maxTimer = TimeSpan.FromSeconds(5);
            var timeout = base.CreateTimeout((int)maxTimer.TotalSeconds * 5);
            long increment = 0;

            using (Timer timer = new Timer(TimeSpan.FromSeconds(1)))
            {
                timer.Elapsed += (o) => { System.Threading.Interlocked.Increment(ref increment); };

                timer.Start(timeout.Token);

                Task.Delay((int)maxTimer.TotalMilliseconds, timeout.Token).Wait();

                Assert.IsTrue(increment >= 4 && increment <= 5);

                timer.Interval = TimeSpan.FromSeconds(2);
                timer.Elapsed += (o) => { System.Threading.Interlocked.Increment(ref increment); };

                Task.Delay((int)timer.Interval.TotalMilliseconds * 5, timeout.Token).Wait();
            }

            Assert.IsTrue(increment >= 11 && increment <= 12);
        }

        [TestCategory(TIMER_CATEGORY)]
        [TestMethod]
        public void Timer_InceptionUsage()
        {
            TimeSpan maxTimer = TimeSpan.FromSeconds(11);
            var timeout = base.CreateTimeout((int)maxTimer.TotalSeconds * 2);
            long increment = 1;

            using (Timer timer = new Timer(TimeSpan.FromSeconds(1)))
            {
                timer.Elapsed += (o) =>
                {
                    timer.Interval = TimeSpan.FromSeconds(System.Threading.Interlocked.Increment(ref increment));
                    Debug.WriteLine(timer.Interval);
                };

                timer.Start(timeout.Token);

                Task.Delay((int)maxTimer.TotalMilliseconds, timeout.Token).Wait();

                timer.Stop();
                Assert.AreEqual(TimeSpan.FromSeconds(5), timer.Interval);
                Assert.AreEqual(5, increment);
            }

        }

        #endregion
    }
}
